package com.asiainfo.dacp.datastash.broker.flow.core.service;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.asiainfo.dacp.datastash.broker.common.cache.BrokerContext;
import com.asiainfo.dacp.datastash.broker.common.repo.UnitRepository;
import com.asiainfo.dacp.datastash.broker.flow.core.domain.Flow;
import com.asiainfo.dacp.datastash.broker.redis.service.RedisFlowService;
import com.asiainfo.dacp.datastash.broker.util.BatchUtils;
import com.asiainfo.dacp.datastash.domain.unit.models.DataStashUnit;
import com.asiainfo.dacp.datastash.orm.po.core.DataStashUnitPo;
import com.google.common.base.Preconditions;

@Service
public class FlowCreateService {
	private static Logger LOG = LoggerFactory.getLogger(FlowCreateService.class);

	@Autowired
	private FlowStateChangeService stateService;

	@Autowired
	private BrokerContext context;

	@Autowired
	private UnitRepository unitRepo;
	
	@Autowired
	private RedisFlowService redisService;

	public void service() {
		// 说明：失败也会是正在运行状态，除非重跑成功或者强制通过
		// 下线需要处理定时任务－目前定时任务无法区分，需要扩字段
		List<DataStashUnitPo> all = unitRepo.allOnlineAndNotRunning();

		LOG.info("流程开始 [{}]", all.size());

		for (DataStashUnitPo one : all) {
			String batchNo = one.getBatchNo();
			LOG.debug("接口 [{}] 批次 [{}] 进入流程判断 .", one.getUnitCode(), batchNo);

			Preconditions.checkNotNull(batchNo);

			String shouldBatchNo = BatchUtils.batchNo(one.getBatchType(), one.getBatchOffset());

			// check-arg
			Preconditions.checkArgument(batchNo.length() == shouldBatchNo.length(),
					String.format("接口 [%s] 批次 [%s] 格式异常 .", one.getUnitCode(), batchNo));

			if (batchNo.compareTo(shouldBatchNo) <= 0) {
				LOG.info("接口 [{}] 批次 [{}] 流程创建开始 .", one.getUnitCode(), batchNo);
				Flow flow = flowCreate(one);
				LOG.info("接口 [{}] 批次 [{}] 流程创建结束, 序列号 [{}].", one.getUnitCode(), batchNo, flow.getSerNo());
			}
		}
	}

	private Flow flowCreate(DataStashUnitPo one) {
		DataStashUnit unit = context.getUnit(one.getId());
		Preconditions.checkNotNull(unit);
		Flow flow = new Flow(unit);
		stateService.flowInit(flow);
		
		// 放入wait队列
		redisService.putUnitWait(flow);
		redisService.createOrUpdate(flow);
		return flow;
	}

}
